/** Base class for a UI.
 *
 * This is the object that the MCP object sends notifications to.
 * UI commands are then sent back to the MCP object. e.g. mcp->command(foo)
 */

#include "mcp.h"
#include "ui.h"

// In the case of something like:
//     time_split(playtime, &hours, &minutes, 0, &millis)
// *millis is set to the number of milliseconds remaining,
// e.g. 48342 if there were 48 seconds and 342 ms.
void UI::time_split (unsigned int time_ms, int *hours, int *minutes,
                                           int *seconds, int *milliseconds)
    {
    if ( hours )
        {
        *hours = time_ms / 1000 / 60 / 60;
        time_ms -= *hours * 60 * 60 * 1000;
        }
    if ( minutes )
        {
        *minutes = time_ms / 1000 / 60;
        time_ms -= *minutes * 60 * 1000;
        }
    if ( seconds )
        {
        *seconds = time_ms / 1000;
        time_ms -= (*seconds * 1000);
        }
    if ( milliseconds )
        *milliseconds = time_ms;
    }

/*  The returned string may be in any of the following formats:
 *      m:ss  mm:ss  hh:mm:ss
 *  For REVERSE display types, the return value is prepended by a minus sign.
 *  hours_check: (ignored if null)
 *      If true, the format is limited to hh:mm rather than hh:mm:ss for
 *      durations over an hour.
 *      The parameter (in either case) is modified upon return to indicate
 *      whether the string includes an hour field.
 */
int UI::playtime_str (char *str, TimeDisplay display, bool *hours_check)
    {
    switch ( display )
        {
        case TIME:
            return time_str(str, mcp->song_position, hours_check);
        case OVERALL_TIME:
            return time_str(str, mcp->total_song_length_previous +
                            mcp->song_position, hours_check);
        case TIME_REVERSE:
            return time_str(str, mcp->song_length -
                            mcp->song_position, hours_check, "-");
        case OVERALL_TIME_REVERSE:
            return time_str(str, mcp->total_song_length -
                            (mcp->total_song_length_previous +
                            mcp->song_position), hours_check, "-");
        default:
            assert(2 + 2 == 5);
            return 0;
        }
    }

/*  FIXME  Internationalise
 */
int UI::time_str (char *str, unsigned int time_ms, bool *hours_check,
                  const char *prefix)
    {
    int result;
    int hours,
        minutes,
        seconds;

    time_split(time_ms, &hours, &minutes, &seconds, 0);

    if ( hours == 0 )
        result = sprintf(str, "%s%01d%s%02d", prefix, minutes, time_separator, seconds);
    else
        {
        if ( hours_check && *hours_check )
            {
            if ( hours > 99 )  // nothing over 2 digits
                result = sprintf(str, "%s9+%s%02d", prefix,
                                 time_separator, minutes);
            else
                result = sprintf(str, "%s%d%s%02d", prefix, hours,
                                 time_separator, minutes);
            }
        else
            {
            if ( hours > 9999 )  // basic sanity check
                result = sprintf(str, "%s9+++%s%02d%s%02d",
                                 prefix, time_separator, minutes,
                                 time_separator,seconds);
            else
                result = sprintf(str, "%s%d%s%02d%s%02d",
                                 prefix, hours, time_separator, minutes,
                                 time_separator, seconds);
            }
        }

    if ( hours_check )
        *hours_check = ( hours > 0 );

    return result;
    }

